home *** CD-ROM | disk | FTP | other *** search
/ Die Ultimative Software-P…i Collection 1996 & 1997 / Die Ultimative Software-Pakete CD-ROM fur Atari Collection 1996 & 1997.iso / g / gnu_c / pmllib21.zoo / mod.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-05  |  5.0 KB  |  259 lines

  1. /************************************************************************
  2.  *                                    *
  3.  *                N O T I C E                *
  4.  *                                    *
  5.  *            Copyright Abandoned, 1987, Fred Fish        *
  6.  *                                    *
  7.  *    This previously copyrighted work has been placed into the    *
  8.  *    public domain by the author (Fred Fish) and may be freely used    *
  9.  *    for any purpose, private or commercial.  I would appreciate    *
  10.  *    it, as a courtesy, if this notice is left in all copies and    *
  11.  *    derivative works.  Thank you, and enjoy...            *
  12.  *                                    *
  13.  *    The author makes no warranty of any kind with respect to this    *
  14.  *    product and explicitly disclaims any implied warranties of    *
  15.  *    merchantability or fitness for any particular purpose.        *
  16.  *                                    *
  17.  ************************************************************************
  18.  */
  19.  
  20.  
  21. /*
  22.  *  FUNCTION
  23.  *
  24.  *    fmod   double precision modulo
  25.  *
  26.  *  KEY WORDS
  27.  *
  28.  *    mod
  29.  *    machine independent routines
  30.  *    math libraries
  31.  *
  32.  *  DESCRIPTION
  33.  *
  34.  *    Returns double precision modulo of two double
  35.  *    precision arguments.
  36.  *
  37.  *  USAGE
  38.  *
  39.  *    double fmod (value, base)
  40.  *    double value;
  41.  *    double base;
  42.  *
  43.  *  PROGRAMMER
  44.  *
  45.  *    Fred Fish
  46.  *
  47.  *    68881 support included by Michael Ritzert
  48.  *
  49.  */
  50.  
  51.  
  52. #include <stdio.h>
  53. #include <math.h>
  54. #include "pml.h"
  55.  
  56. #if !defined (__M68881__) && !defined (sfp004)    /* mjr++    */
  57.  
  58. double fmod (value, base)
  59. double value;
  60. double base;
  61. {
  62.     double intpart;
  63.  
  64.     value /= base;
  65.     value = modf (value, &intpart);
  66.     value *= base;
  67.     return (value);
  68. }
  69. #endif    /* __M68881, sfp004    */
  70. #ifdef    sfp004
  71.  
  72. __asm("
  73.  
  74. | base =    0xfffa50
  75. |      the fpu addresses are taken relativ to 'base':
  76. comm =     -6
  77. resp =    -16
  78. zahl =      0
  79.  
  80. ");    /* end asm    */
  81.  
  82. #endif    sfp004
  83. #if defined (__M68881__) || defined (sfp004)
  84.  
  85.     __asm(".text; .even");
  86.  
  87. # ifdef    ERROR_CHECK
  88.  
  89.     __asm("
  90.  
  91.  
  92. _Overflow:
  93.     .ascii \"OVERFLOW\\0\"
  94. _Domain:
  95.     .ascii \"DOMAIN\\0\"
  96. _Error_String:
  97.     .ascii \"fmod: %s error\\n\\0\"
  98.  
  99. | pml compatible tangent
  100. | m.ritzert 7.12.1991
  101. | ritzert@dfg.dbp.de
  102. |
  103. |    /* NAN  = {7fffffff,ffffffff}        */
  104. |    /* +Inf = {7ff00000,00000000}        */
  105. |    /* -Inf = {fff00000,00000000}        */
  106. |    /* MAX_D= {7fee42d1,30773b76}        */
  107. |    /* MIN_D= {ffee42d1,30773b76}        */
  108.  
  109. .even
  110. double_max:
  111.     .long    0x7fee42d1
  112.     .long    0x30273b76
  113. double_min:
  114.     .long    0xffee42d1
  115.     .long    0x30273b76
  116. NaN:
  117.     .long    0x7fffffff
  118.     .long    0xffffffff
  119. p_Inf:
  120.     .long    0x7ff00000
  121.     .long    0x00000000
  122. m_Inf:
  123.     .long    0xfff00000
  124.     .long    0x00000000
  125.     ");    /* end asm    */
  126. # endif    ERROR_CHECK
  127.  
  128.     __asm(".even
  129.     .globl _fmod
  130. _fmod:
  131.     ");    /* end asm    */
  132.  
  133. #endif    /* __M68881__ || sfp004    */
  134. #ifdef    __M68881__
  135.  
  136.     __asm("
  137.     fmovex    fp0,sp@-    | 12 Bytes
  138.     fmoved    a7@(16), fp0    | value
  139.     fmodd    a7@(24),fp0    | base
  140.     fmoved    fp0,a7@-    | push result
  141.     moveml    a7@+,d0-d1    | return_value
  142.     fmovex    sp@+,fp0
  143.     ");    /* end asm    */
  144.  
  145. #endif    __M68881__
  146. #ifdef    sfp004
  147.     __asm("
  148.     lea    0xfffa50,a0
  149.     movew    #0x5400,a0@(comm)    | specify function (fmove)
  150.     cmpiw    #0x8900,a0@(resp)    | check
  151.     movel    a7@(4),a0@        | load arg_hi
  152.     movel    a7@(8),a0@        | load arg_low
  153.     movew    #0x5421,a0@(comm)    | specify function (fmod)
  154.     .long    0x0c688900, 0xfff067f8    | wait
  155.     movel    a7@(12),a0@        | load arg_hi
  156.     movel    a7@(16),a0@        | load arg_low
  157.     movew    #0x7400,a0@(comm)    | result to d0
  158.     .long    0x0c688900, 0xfff067f8    | wait
  159.     movel    a0@,d0
  160.     movel    a0@,d1
  161.     ");    /* end asm    */
  162.  
  163. #endif    sfp004
  164. #if defined (__M68881__) || defined (sfp004)
  165. # ifdef    ERROR_CHECK
  166.     __asm("
  167.     lea    double_max,a0    |
  168.     swap    d0        | exponent into lower word
  169.     cmpw    a0@(16),d0    | == NaN ?
  170.     beq    error_nan    |
  171.     cmpw    a0@(24),d0    | == + Infinity ?
  172.     beq    error_plus    |
  173.     cmpw    a0@(32),d0    | == - Infinity ?
  174.     beq    error_minus    |
  175.     swap    d0        | result ok,
  176.     rts            | restore d0
  177. ");
  178. #ifndef    __MSHORT__
  179. __asm("
  180. error_minus:
  181.     swap    d0
  182.     moveml    d0-d1,a7@-
  183.     movel    #63,_errno    | errno = ERANGE
  184.     pea    _Overflow    | for printf
  185.     bra    error_exit    |
  186. error_plus:
  187.     swap    d0
  188.     moveml    d0-d1,a7@-
  189.     movel    #63,_errno    | NAN => errno = EDOM
  190.     pea    _Overflow    | for printf
  191.     bra    error_exit    |
  192. error_nan:
  193.     moveml    a0@(24),d0-d1    | result = +inf
  194.     moveml    d0-d1,a7@-
  195.     movel    #62,_errno    | NAN => errno = EDOM
  196.     pea    _Domain        | for printf
  197. ");
  198. #else    __MSHORT__
  199. __asm("
  200. error_minus:
  201.     swap    d0
  202.     moveml    d0-d1,a7@-
  203.     movew    #63,_errno    | errno = ERANGE
  204.     pea    _Overflow    | for printf
  205.     bra    error_exit    |
  206. error_plus:
  207.     swap    d0
  208.     moveml    d0-d1,a7@-
  209.     movew    #63,_errno    | NAN => errno = EDOM
  210.     pea    _Overflow    | for printf
  211.     bra    error_exit    |
  212. error_nan:
  213.     moveml    a0@(24),d0-d1    | result = +inf
  214.     moveml    d0-d1,a7@-
  215.     movew    #62,_errno    | NAN => errno = EDOM
  216.     pea    _Domain        | for printf
  217. ");
  218. #endif    __MSHORT__
  219. __asm("
  220. error_exit:
  221.     pea    _Error_String    |
  222.     pea    __iob+52    |
  223.     jbsr    _fprintf    |
  224.     addl    #12,a7        |
  225.     rts
  226.     ");
  227. # else    ERROR_CHECK
  228.  
  229. __asm("rts");
  230.  
  231. # endif    ERROR_CHECK
  232. #endif /* __M68881__ || sfp004    */
  233.  
  234. #ifdef m68881
  235. /* mjr: intermediate version, remove after debugging    */
  236.  
  237.     struct exception xcpt;
  238.  
  239. double fmod (double value, double base)
  240. {
  241.     if( base == 0.0 )    {
  242.     xcpt.retval = HUGE_VAL;
  243.     if( value < 0.0 ) xcpt.retval = -HUGE_VAL;
  244.     xcpt.arg1 = base;
  245.     xcpt.type = DOMAIN;
  246.     if (!matherr (&xcpt)) {
  247.         fprintf (stderr, "%s: ZERO DIVIDE error\n", "fmod");
  248.         errno = EDOM;
  249.     }
  250.     } else {
  251.     __asm ("fmod%.x %2,%0"
  252.      : "=f" (xcpt.retval)
  253.      : "0" (value),
  254.        "f" (base));
  255.     }
  256.     return xcpt.retval;
  257. }
  258. #endif m68881
  259.